from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View

#from myapp.models import User
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F

#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

from myapp.models import User,Cate
from myapp.myser import CateSer,UserSer

import base64
import hmac
from hashlib import sha256
import urllib


#导包
import redis

#定义ip地址和端口
host = "127.0.0.1"
port = 6379

#链接对象
r = redis.Redis(host=host, port=port)


from django.utils.deprecation import MiddlewareMixin


# 自定义中间件
class MyMiddleWare(MiddlewareMixin):

	#请求之前
	def process_request(self, request):
		# uid = request.GET.get('uid')
		# clinet_jwt = request.GET.get('jwt',None)

		# if clinet_jwt == None:
		# 	return HttpResponse("您没有携带令牌")

		# decode_jwt = jwt.decode(clinet_jwt, '199706', algorithms=['HS256'])

		# if (decode_jwt['uid'] != str(uid)):
		# 	return HttpResponse('您篡改了用户信息')
		
		pass

	#模板渲染之前
	def process_view(self, request, view_func, view_args, view_kwargs):
		
		pass

	#请求之后
	def process_response(self, request, response):
		return response


# 装饰器
def my_decorator(func):
	def wrapper(request,*args,**kwargs):
		
		# # 判断jwt
		# uid = request.GET.get('uid')
		# clinet_jwt = request.GET.get('jwt',None)

		# if clinet_jwt == None:
		# 	return HttpResponse("您没有携带令牌")

		# decode_jwt = jwt.decode(clinet_jwt, '199706', algorithms=['HS256'])

		# if (decode_jwt['uid'] != str(uid)):
		# 	return HttpResponse('您篡改了用户信息')

		return func(request,*args,**kwargs)
	return wrapper

# 类装饰器调用
from django.utils.decorators import method_decorator

# 用户信息
class UserInfo(APIView):
	@method_decorator(my_decorator)
	def get(self,request):
		uid = request.GET.get('uid')

		# 查询数据
		user = User.objects.get(id=int(uid))

		# 序列化对象
		user_ser = UserSer(user)

		return Response(user_ser.data)


# 更新用户数据
class UpdateUser(APIView):
	def get(self,request):

		img = request.GET.get('img')
		uid = request.GET.get('uid')

		# 查询数据
		user = User.objects.get(id=int(uid))
		user.img = img
		user.save()

		return Response({'code':200,'message':"更新成功"})



# 定义七牛云存储接口
from qiniu import Auth

class QiNiu(APIView):

	def get(self,request):
		
		# 定义密钥
		q = Auth('5Veq6sNOg8ka1d9uIeOS3Wazb7AESwvrBbCsdJWi',
		         '_8g1em1f0XJ-Ge4AoxZhNSc3p1HnqvhqFuC6UNcJ')
		
		# 指定上传控件
		token = q.upload_token('1906md')

		print(token)

		res = {}
		res['token'] = token

		return Response(res)


# 修改密码
class UploadUser(APIView):
	def get(self, request):
		uid = request.GET.get("uid")
		password = request.GET.get('password')
		password1 = request.GET.get("password1")

		# print('..........',uid)

		if(password!=password1):
			res = {}
			res['code'] = 401
			res['message'] = "两次密码不一致"
			return Response(res)
		
		user = User.objects.filter(id=uid).first()
		
		user.password = "password"
		user.save()
		res = {}
		res['code'] = 200
		res['message'] = "修改成功"
		return Response(res)





#定义上传视图类
class UploadFile(View):

	def post(self, request):

		#接收参数
		img = request.FILES.get("file")

		#建立文件流对象
		f = open(os.path.join(UPLOAD_ROOT, '', img.name), 'wb')

		#写入服务器端
		for chunk in img.chunks():
			f.write(chunk)
		f.close()

		#返回文件名
		return HttpResponse(json.dumps({'filename': img.name}, ensure_ascii=False), content_type='application/json')



#递归层级关系
def xTree(datas):
	lists = []
	tree = {}
	parent_id = ''

	for i in datas:
		item = i
		tree[item['id']] = item

	root = None
	for i in datas:
		obj = i
		if not obj['pid']:
			root = tree[obj['id']]
			lists.append(root)
		else:
			parent_id = obj['pid']
			if 'childlist' not in tree[parent_id]:
				tree[parent_id]['childlist'] = []
			tree[parent_id]['childlist'].append(tree[obj['id']])

	return lists


def ding_back(request):
    #获取code
    code = request.GET.get("code")

    t = time.time()

    # 时间戳
    timestamp = str((int(round(t * 1000))))
    appSecret = 'fp3nkGoIhS2Mi9EdVql_nKXg6Y0-HSGp-2F_p7IAv_Quc56yhhrinpqbcQRg3RqF'

    # 构造签名
    signature = base64.b64encode(hmac.new(appSecret.encode(
    	'utf-8'), timestamp.encode('utf-8'), digestmod=sha256).digest())

    # 请求接口，换取钉钉用户名
    payload = {'tmp_auth_code': code}
    headers = {'Content-Type': 'application/json'}
    res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature='+urllib.parse.quote(signature.decode(
    	"utf-8"))+"&timestamp="+timestamp+"&accessKey=dingoahmelrgy51wltnjzs", data=json.dumps(payload), headers=headers)

    res_dict = json.loads(res.text)
    print(res_dict)
    # return HttpResponse(res.text)

    # 判断是否为第一次钉钉登录
    user = User.objects.filter(username=str(res_dict['user_info']['nick'])).first()

    ding_id = ''
    user_id = ''

    if user:
        # 代表曾经用过钉钉登录
        ding_id = user.username
        user_id = user.id

    else:
        # 代表首次登录，入库
        user = User(username=str(res_dict['user_info']['nick']), password='')
        # 保存入库
        user.save()

        # 查询用户id
        user = User.objects.filter(username=str(
            res_dict['user_info']['nick'])).first()
        ding_id = str(res_dict['user_info']['nick'])
        user_id = user.id
    # 进行跳转
    return redirect('http://localhost:8080?ding_id=' + str(ding_id) + '&uid=' + str(user_id))

# 新浪微博回调试图
def weibo_back(request):

    # 获取code
    code = request.GET.get('code')

    # 换取网址
    access_token_url = "https://api.weibo.com/oauth2/access_token"

    # 发送请求进行换取
    re_dict = requests.post(
        access_token_url,
        data={

            "client_id": '2636039333',
            "client_secret": "4e2fbdb39432c31dc5c2f90be3afa5ce",
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": "http://127.0.0.1:8000/md_admin/weibo"

        }
    ).text
    # print('////////////////', re_dict)
    re_dict = eval(re_dict)


    # 判断是否用微博登陆过
    user = User.objects.filter(username=str(re_dict['uid'])).first()

    sina_id = ""
    user_id = ""

    if user:
        # 曾经登陆过
        sina_id = user.username
        user_id = user.id

    else:
        # 没有登陆过，自动注册
        user = User(username=str(re_dict['uid']), password='', type=0)
        # 保存
        user.save()

        # 查询用户id
        user = User.objects.filter(username=str(re_dict['uid'])).first()

        sina_id = str(re_dict['uid'])
        user_id = user.id

    # 跳转
    return redirect("http://localhost:8080?sina_id="+str(sina_id)+"&uid="+str(user_id))




class MyTree(APIView):

	def get(self,request):

		#获取数据
		catelist = Cate.objects.filter()
		#序列化操作
		cate_ser = CateSer(catelist,many=True)
		#格式化改造
		mylist = xTree(cate_ser.data)

		return Response(mylist)



#md5加密方法
def make_password(mypass):

	#生成md5对象
	md5 = hashlib.md5()
	#定义机密对象
	sign_str = str(mypass)
	#转码
	sign_utf8 = sign_str.encode(encoding="utf-8")
	#加密
	md5.update(sign_utf8)
	#生成密钥串
	md5_server = md5.hexdigest()

	return md5_server


# 登录
class Login(APIView):

	def get(self,request):
		# 获取用户名
		username = request.GET.get('username', 'null')
		# 获取密码
		password = request.GET.get('password', 'null')

		# 验证信息是否正确
		user = User.objects.filter(username=username, password=make_password(password)).first()

		# 如果信息正确
		if user:
			res={}
			res['code'] = 200
			res['message'] = "登陆成功"
			res['username'] = user.username
			res['uid'] = user.id

			# 加入jwt令牌机制
			# 进行编码
			encode_jwt = jwt.encode({'uid': str(user.id)}, '199706', algorithm='HS256')
			# 解码
			# 强转
			encode_str = str(encode_jwt, 'utf-8')
			res['jwt'] = encode_str
			return Response(res)

		# 如果错误
		res = {}
		res['code'] = 401
		res['message'] = "信息错误"
		return Response(res)


#定义验证码类
class MyCode(View):

	#定义随机颜色
	def get_random_color(self):
		R = random.randrange(255)
		G = random.randrange(255)
		B = random.randrange(255)
		return (R,G,B)

	#获取验证码视图
	def get(self,request):
		#画布
		img_size = (200,100)
		#定义画图对象
		image = Image.new('RGB',img_size,'white')
		#定义画笔对象
		draw = ImageDraw.Draw(image,'RGB')
		#定义随机字符串
		source = 'hvhsdfjhkbaskjdfbvhkj'
		#容器
		code_str = ''
		#定义字体
		my_font = ImageFont.truetype(font="C:\\Windows\\Fonts\\framdit.ttf", size=50)
		for i in range(4):
			#获取随机颜色
			text_color = self.get_random_color()
			#获取随机字符串长度下标
			tmp_num = random.randrange(len(source))
			#获取字符集
			random_str = source[tmp_num]
			#添加到容器中
			code_str += random_str
			#将字符串添加到画布中去
			draw.text((10+30*i,20),random_str,text_color,font=my_font)

		# 将验证码存储到session中
		# request.session['code'] = code_str
		# code = request.session.get('code')
		# print('----', code)

		#建立缓存区
		buf = io.BytesIO()

		#将验证码存储到redis中
		r.set('code',code_str)

		#保存图片
		image.save(buf,'png')
		return HttpResponse(buf.getvalue(),'image/png')



#注册模块
class Register(APIView):

	def get(self,request):

		#接收参数  dict['username']
		username = request.GET.get('username','null')
		password = request.GET.get('password','null')
		code = request.GET.get('code','null')

		print(username)
		print(password)
		print("获取的",code)

		#获取验证码
		redis_code = r.get('code')
		redis_code = redis_code.decode('utf-8')
		print(redis_code)

		# 获取session中的验证码
		# code_str = request.session.get('code')
		# print('获取session的',code_str)

		#判断验证码是否正确
		if code != redis_code:
			res = {}
			res['code'] = 405
			res['message'] = '验证码输入错误'
			return Response(res)

		#排重
		user = User.objects.filter(username=username).first()

		if user:
			res = {}
			res['code'] = 405
			res['message'] = '该用户名已存在'
			return Response(res)

		#入库
		user = User(username=username,password=make_password(password))
		user.save()

		res = {}
		res['code'] = 200
		res['message'] = '恭喜，注册成功'

		return Response(res)








#方法视图
def myindex(request):

    return HttpResponse('这里是首页')


#类视图
class MyView(View):

	greeting = '你好啊'

	def get(self,request):

		title = "你好啊，Django"
		num = 100
		li = [1,2,3,4,5]
		dic = {'name':'汽车','price':100}

		#渲染模板
		return render(request,'index.html',locals())

		#return HttpResponse(self.greeting)


